package com.ruoyi.web.controller.app;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.AppLoginService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.IAppUserService;
import io.lettuce.core.models.stream.ClaimedMessages;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

/**
 * 理赔用户登录相关接口
 */
@Api(value = "理赔用户登录接口", description = "提供理赔用户登录、重置密码、注销等操作接口")
@RestController
@RequestMapping("/app/user")
@Anonymous
@RequiredArgsConstructor
public class UserCenterController {

    private final AppLoginService appLoginService;
    private final IAppUserService iAppUserService;
    private final TokenService tokenService;

    /**
     * 登录方法
     *
     * @param appUser 登录信息
     * @return 结果
     */
    @ApiOperation(value = "理赔用户登录", notes = "根据用户名和密码进行理赔用户登录，登录成功返回令牌")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户登录使用的用户名", required = true, dataType = "String", example = "test_user"),
            @ApiImplicitParam(name = "password", value = "用户登录密码", required = true, dataType = "String", example = "123456")
    })
    @PostMapping("/login")
    public AjaxResult appLogin(@RequestBody  AppUser appUser) {
        if(!StrUtil.isAllNotBlank(appUser.getUserName(), appUser.getPassword())){
            throw new ServiceException("账号或密码不能为空！");
        }
        AjaxResult ajax = AjaxResult.success();
        LambdaQueryWrapper<AppUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AppUser::getUserName, appUser.getUserName());
        //String pwdStr = SecurityUtils.encryptPassword(appUser.getPassword());
        AppUser user = iAppUserService.getOne(lambdaQueryWrapper);
        if(user == null || !SecurityUtils.matchesPassword(appUser.getPassword(), user.getPassword())){
            throw new ServiceException("账号或密码错误");
        }
        // 生成令牌
        String token = appLoginService.login(user.getUserName(), appUser.getPassword(), "",
                "");
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 登录方法
     *
     * @param appUser 登录信息
     * @return 结果
     */
    @ApiOperation(value = "理赔用户登录", notes = "根据用户名和密码进行理赔用户登录，登录成功返回令牌")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户登录使用的用户名", required = true, dataType = "String", example = "test_user"),
            @ApiImplicitParam(name = "password", value = "用户登录密码", required = true, dataType = "String", example = "123456"),
            @ApiImplicitParam(name = "idCard", value = "身份证号码", required = true, dataType = "String", example = "123456")
    })
    @PostMapping("/register")
    public AjaxResult register(@RequestBody @Valid AppUser appUser) {
        if(StringUtils.isNull(appUser.getUserName()) || StringUtils.isNull(appUser.getPassword()) || StringUtils.isNull(appUser.getIdCard())){
            throw new ServiceException("用户名、密码和身份证不能为空");
        }
        AjaxResult ajax = AjaxResult.success();
        LambdaQueryWrapper<AppUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AppUser::getUserName, appUser.getUserName()).or()
        .eq(AppUser::getIdCard, appUser.getIdCard());
        AppUser user = iAppUserService.getOne(lambdaQueryWrapper);
        if(user != null){
            throw new ServiceException("已存在相同的账号或者身份证");
        }
        String pwdStr = SecurityUtils.encryptPassword(appUser.getPassword());
        appUser.setPassword(pwdStr);
        iAppUserService.save(appUser);
        return ajax;
    }

    /**
     * 重置密码
     * @param appUser 包含用户名和身份证信息的用户对象
     * @return 操作结果
     */
    @ApiOperation(value = "重置用户密码", notes = "根据用户名和身份证信息验证用户身份，验证通过后重置密码")
    @ApiImplicitParams({

            @ApiImplicitParam(name = "userName", value = "用户登录使用的用户名", required = true, dataType = "String", example = "test_user"),
            @ApiImplicitParam(name = "password", value = "用户登录密码", required = true, dataType = "String", example = "123456"),
            @ApiImplicitParam(name = "idCard", value = "用户的身份证号码", required = true, dataType = "String", example = "11010119900307551X")
    })
    @PostMapping("/resetPwd")
    public AjaxResult findPwd(@RequestBody AppUser appUser) {
        LambdaQueryWrapper<AppUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AppUser::getUserName, appUser.getUserName());
        lambdaQueryWrapper.eq(AppUser::getIdCard, appUser.getIdCard());
        AppUser user = iAppUserService.getOne(lambdaQueryWrapper);
        if(user == null){
            throw new ServiceException("账户和身份证不匹配");
        }
        user.setPassword(SecurityUtils.encryptPassword(appUser.getPassword()));
        iAppUserService.updateById(user);
        return AjaxResult.success();
    }

    /**
     * 注销
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 操作结果
     */
    @ApiOperation(value = "用户注销", notes = "用户退出登录，删除用户缓存记录并记录退出日志")

    @PostMapping("/logout")
    public AjaxResult logonOut(HttpServletRequest request, HttpServletResponse response) {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            String userName = loginUser.getUser().getUserName();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
        }
        //ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success"))));
        return AjaxResult.success();
    }
}
